package com.kexio.pay.provider;

import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kexio.pay.dto.PaymentRequest;
import com.kexio.pay.dto.PaymentResponse;
import com.kexio.pay.entity.PaymentCallback;
import com.kexio.pay.enums.PaymentMethod;
import com.kexio.pay.enums.PaymentStatus;

import cn.hutool.core.util.StrUtil;

/**
 * 抽象支付提供商基类
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public abstract class AbstractPaymentProvider implements PaymentProvider {
    
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Override
    public boolean isSupported(PaymentMethod method) {
        Set<PaymentMethod> supportedMethods = getSupportedMethods();
        return supportedMethods != null && supportedMethods.contains(method);
    }
    
    @Override
    public PaymentResponse createPayment(PaymentRequest request) {
        try {
            // 基本参数验证
            if (request == null) {
                return PaymentResponse.failure("INVALID_REQUEST", "支付请求不能为空");
            }
            
            if (StrUtil.isBlank(request.getOrderNo())) {
                return PaymentResponse.failure("INVALID_ORDER_NO", "订单号不能为空");
            }
            
            if (request.getAmount() == null || request.getAmount().compareTo(java.math.BigDecimal.ZERO) <= 0) {
                return PaymentResponse.failure("INVALID_AMOUNT", "支付金额必须大于0");
            }
            
            if (StrUtil.isBlank(request.getPaymentMethod())) {
                return PaymentResponse.failure("INVALID_PAYMENT_METHOD", "支付方式不能为空");
            }
            
            // 检查是否支持该支付方式
            PaymentMethod method = PaymentMethod.fromCode(request.getPaymentMethod());
            if (!isSupported(method)) {
                return PaymentResponse.failure("UNSUPPORTED_METHOD", 
                    "不支持的支付方式: " + request.getPaymentMethod());
            }
            
            // 检查配置
            if (!isConfigured()) {
                return PaymentResponse.failure("PROVIDER_NOT_CONFIGURED", 
                    getProviderId() + " 支付提供商未正确配置");
            }
            
            logger.info("开始创建支付订单: provider={}, orderNo={}, method={}, amount={}", 
                       getProviderId(), request.getOrderNo(), request.getPaymentMethod(), request.getAmount());
            
            // 调用具体实现
            PaymentResponse response = doCreatePayment(request);
            
            if (response.isSuccess()) {
                logger.info("支付订单创建成功: provider={}, orderNo={}, thirdPartyOrderNo={}", 
                           getProviderId(), request.getOrderNo(), response.getThirdPartyOrderNo());
            } else {
                logger.warn("支付订单创建失败: provider={}, orderNo={}, error={}", 
                           getProviderId(), request.getOrderNo(), response.getMessage());
            }
            
            return response;
            
        } catch (Exception e) {
            logger.error("创建支付订单异常: provider={}, orderNo={}", 
                        getProviderId(), request != null ? request.getOrderNo() : "null", e);
            return PaymentResponse.failure("SYSTEM_ERROR", "系统异常: " + e.getMessage());
        }
    }
    
    @Override
    public PaymentStatus queryPayment(String orderNo, String thirdPartyOrderNo) {
        try {
            if (StrUtil.isBlank(orderNo) && StrUtil.isBlank(thirdPartyOrderNo)) {
                logger.warn("查询支付状态参数无效: orderNo和thirdPartyOrderNo都为空");
                return PaymentStatus.FAILED;
            }
            
            if (!isConfigured()) {
                logger.warn("支付提供商未配置: {}", getProviderId());
                return PaymentStatus.FAILED;
            }
            
            logger.debug("查询支付状态: provider={}, orderNo={}, thirdPartyOrderNo={}", 
                        getProviderId(), orderNo, thirdPartyOrderNo);
            
            return doQueryPayment(orderNo, thirdPartyOrderNo);
            
        } catch (Exception e) {
            logger.error("查询支付状态异常: provider={}, orderNo={}, thirdPartyOrderNo={}", 
                        getProviderId(), orderNo, thirdPartyOrderNo, e);
            return PaymentStatus.FAILED;
        }
    }
    
    @Override
    public boolean closePayment(String orderNo, String thirdPartyOrderNo) {
        try {
            if (StrUtil.isBlank(orderNo) && StrUtil.isBlank(thirdPartyOrderNo)) {
                logger.warn("关闭支付订单参数无效: orderNo和thirdPartyOrderNo都为空");
                return false;
            }
            
            if (!isConfigured()) {
                logger.warn("支付提供商未配置: {}", getProviderId());
                return false;
            }
            
            logger.info("关闭支付订单: provider={}, orderNo={}, thirdPartyOrderNo={}", 
                       getProviderId(), orderNo, thirdPartyOrderNo);
            
            boolean result = doClosePayment(orderNo, thirdPartyOrderNo);
            
            if (result) {
                logger.info("支付订单关闭成功: provider={}, orderNo={}", getProviderId(), orderNo);
            } else {
                logger.warn("支付订单关闭失败: provider={}, orderNo={}", getProviderId(), orderNo);
            }
            
            return result;
            
        } catch (Exception e) {
            logger.error("关闭支付订单异常: provider={}, orderNo={}, thirdPartyOrderNo={}", 
                        getProviderId(), orderNo, thirdPartyOrderNo, e);
            return false;
        }
    }
    
    @Override
    public boolean verifyCallback(PaymentCallback callback) {
        try {
            if (callback == null) {
                logger.warn("回调数据为空");
                return false;
            }
            
            if (!getProviderId().equals(callback.getProvider())) {
                logger.warn("回调提供商不匹配: expected={}, actual={}", 
                           getProviderId(), callback.getProvider());
                return false;
            }
            
            if (!isConfigured()) {
                logger.warn("支付提供商未配置: {}", getProviderId());
                return false;
            }
            
            logger.debug("验证回调签名: provider={}, orderNo={}", 
                        getProviderId(), callback.getOrderNo());
            
            return doVerifyCallback(callback);
            
        } catch (Exception e) {
            logger.error("验证回调签名异常: provider={}, orderNo={}", 
                        getProviderId(), callback != null ? callback.getOrderNo() : "null", e);
            return false;
        }
    }
    
    @Override
    public CallbackResult processCallback(PaymentCallback callback) {
        try {
            if (callback == null) {
                return CallbackResult.failure("回调数据为空");
            }
            
            if (!getProviderId().equals(callback.getProvider())) {
                return CallbackResult.failure("回调提供商不匹配");
            }
            
            if (!isConfigured()) {
                return CallbackResult.failure("支付提供商未配置");
            }
            
            logger.info("处理支付回调: provider={}, orderNo={}, type={}", 
                       getProviderId(), callback.getOrderNo(), callback.getCallbackType());
            
            // 先验证签名
            if (!verifyCallback(callback)) {
                logger.warn("回调签名验证失败: provider={}, orderNo={}", 
                           getProviderId(), callback.getOrderNo());
                return CallbackResult.failure("签名验证失败");
            }
            
            // 处理回调
            CallbackResult result = doProcessCallback(callback);
            
            if (result.isSuccess()) {
                logger.info("回调处理成功: provider={}, orderNo={}, status={}", 
                           getProviderId(), callback.getOrderNo(), result.getStatus());
            } else {
                logger.warn("回调处理失败: provider={}, orderNo={}, message={}", 
                           getProviderId(), callback.getOrderNo(), result.getMessage());
            }
            
            return result;
            
        } catch (Exception e) {
            logger.error("处理支付回调异常: provider={}, orderNo={}", 
                        getProviderId(), callback != null ? callback.getOrderNo() : "null", e);
            return CallbackResult.failure("系统异常: " + e.getMessage());
        }
    }
    
    // 抽象方法，由具体实现类提供
    
    /**
     * 创建支付订单 (具体实现)
     */
    protected abstract PaymentResponse doCreatePayment(PaymentRequest request);
    
    /**
     * 查询支付状态 (具体实现)
     */
    protected abstract PaymentStatus doQueryPayment(String orderNo, String thirdPartyOrderNo);
    
    /**
     * 关闭支付订单 (具体实现)
     */
    protected abstract boolean doClosePayment(String orderNo, String thirdPartyOrderNo);
    
    /**
     * 验证回调签名 (具体实现)
     */
    protected abstract boolean doVerifyCallback(PaymentCallback callback);
    
    /**
     * 处理回调数据 (具体实现)
     */
    protected abstract CallbackResult doProcessCallback(PaymentCallback callback);
    
    /**
     * 生成随机字符串 (用于订单号等)
     */
    protected String generateRandomString(int length) {
        return cn.hutool.core.util.RandomUtil.randomString(length);
    }
    
    /**
     * 获取当前时间戳
     */
    protected long getCurrentTimestamp() {
        return System.currentTimeMillis();
    }
}
